package com.team5101;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSONObject;
import com.team5101.configEntity.Constant;
import com.team5101.configEntity.DriudPoolConf;
import com.team5101.configEntity.ZooKeeperProperties;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WebZkconfigApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(WebZkconfigApplication.class, args);
    }

    private Logger logger = LoggerFactory.getLogger(WebZkconfigApplication.class);

    public static DruidDataSource dataSource = null;

    private final CuratorFramework curatorFramework;

    private final ZooKeeperProperties zkProperties;

    public WebZkconfigApplication(CuratorFramework curatorFramework, ZooKeeperProperties zkProperties) {
        this.curatorFramework = curatorFramework;
        this.zkProperties = zkProperties;
    }

//    public static void main(String[] args) {
//        SpringApplication.run(WebZkconfigApplication.class);
//    }

    @Override
    public void run(String... args) throws Exception {

        String zkConfigPath = "/" + Constant.ZKCONFIG;

        //连接zk服务端
        curatorFramework.start();
        curatorFramework.blockUntilConnected();
        logger.info("当前应用 已连接上zookeeper服务端：{}", zkProperties.getZkHost() + ":" + zkProperties.getPort());

        setListeners(zkConfigPath);
    }

    private void setListeners(String path) throws Exception {

        PathChildrenCache childrenCache = new PathChildrenCache(curatorFramework, path, true);
        PathChildrenCacheListener childrenCacheListener = (client, event) -> {
            ChildData data = event.getData();

            switch (event.getType()) {
                //添加子节点
                case CHILD_ADDED:
                    String nodeData = new String(data.getData());
                    logger.info("~~~~~~ 新增子节点事件 获取连接");
                    createPool(data, nodeData);
                    break;
                //移除子节点
                case CHILD_REMOVED:
                    logger.info("~~~~~~ 移除子节点事件 关闭连接");
                    if (data.getPath().contains("database")) {
                        dataSource = null;
                    }
                    break;
                //子节点的数据变化
                case CHILD_UPDATED:
                    String nodeDataa = new String(data.getData());
                    logger.info("~~~~~~ 子节点数据变化事件 重新获取连接");
                    createPool(data, nodeDataa);
                    break;
                default:
                    break;
            }
        };
        childrenCache.getListenable().addListener(childrenCacheListener);
        childrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
    }

    private void createPool(ChildData data, String nodeData) {
        if (data.getPath().contains("database")) {
            DriudPoolConf driudPoolConf = JSONObject.parseObject(nodeData, DriudPoolConf.class);
            logger.info("创建数据源：{}", nodeData);
            dataSource = new DruidDataSource();
            dataSource.setUrl(driudPoolConf.getUrl());
            dataSource.setUsername(driudPoolConf.getUsername());
            dataSource.setPassword(driudPoolConf.getPassword());
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        }
    }

}
